using System;
using System.Collections.Generic;
using XcoAppSpaces.Contracts.CcrWiring;
using XcoAppSpaces.Contracts.Communication;
using XcoAppSpaces.Contracts.Exceptions;
using XcoAppSpaces.Contracts.Security;
using XcoAppSpaces.Contracts.Serialization;
using XcoAppSpaces.Contracts.Service;
using XcoAppSpaces.Contracts.Transport;

namespace XcoAppSpaces.Core.Configuration
{
	/// <summary>
	/// Defines the service implementations and config string interpreters that are used by default.
	/// </summary>
	static class DefaultServices
	{
		private static readonly Dictionary<Type, Func<IXcoService>> Defaults =
			new Dictionary<Type, Func<IXcoService>>
				{
					{typeof (IXcoTransportService), () => new XcoAppSpaces.Transport.Sockets.XcoTCPTransportService()},
					{typeof (IXcoSerializer), () => DefaultSerializer},
					{typeof (IXcoSecurityService), () => new XcoAppSpaces.Security.Basic.XcoNoSecurityService()},
					{typeof (IConnector), () => new XcoAppSpaces.Core.Communication.Connector()},
					{typeof (ICcrWirer), () => new XcoAppSpaces.Core.CcrWiring.CcrWirer()},
				};

		public static T GetDefault<T>() where T : IXcoService
		{
			var type = typeof (T);
			if (!Defaults.ContainsKey(type))
				throw new XcoConfigurationException("No default service implementation known for type " + type);
			return (T)Defaults[type]();
		}

		private static IXcoSerializer DefaultSerializer
		{
#if PocketPC || SILVERLIGHT
			get { return new XcoAppSpaces.Serialization.Json.XcoJsonSerializer(); }
#else
			get { return new XcoAppSpaces.Serialization.Binary.XcoBinarySerializer(); }
#endif
		}
	}
}